/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.machineryrental.dao.impl;

import cz.muni.fi.pa165.machineryrental.dao.CustomerDAO;
import cz.muni.fi.pa165.machineryrental.entities.Customer;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.hibernate.service.spi.ServiceException;

/**
 * Implementation of CustomerDAO which is used on persisting and other
 * operations on customers in database.
 *
 * @author Jozef Triscik
 */
public class CustomerDAOImpl implements CustomerDAO {

    /**
     * Entity Manager for performing operations in or from database.
     */
    private EntityManager em;

    /**
     * Creates new instance of CustomerDAOImpl on performing operations on
     * entities into or from database.
     *
     * @param em Entity manager running the operations to database.
     */
    public CustomerDAOImpl(EntityManager em) {
        if (em == null) {
            throw new IllegalArgumentException("Given Entity manager cannot be null.");
        }

        this.em = em;
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#getById(int)
     */
    @Override
    public Customer getById(long id) {
        if (id < 0) {
            throw new IllegalArgumentException("ID cannot be negative");
        }

        return em.find(Customer.class, id);
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#create(cz.muni.fi.pa165.machineryrental.entities.Customer)
     */
    @Override
    public void create(Customer customer) {
        if (customer == null) {
            throw new IllegalArgumentException("Customer cannot be null");
        }

        this.em.persist(customer);
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#update(cz.muni.fi.pa165.machineryrental.entities.Customer)
     */
    @Override
    public void update(Customer customer) {
        if (customer == null) {
            throw new IllegalArgumentException("Customer cannot be null");
        }

        this.em.merge(customer);
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#remove(cz.muni.fi.pa165.machineryrental.entities.Customer)
     */
    @Override
    public void remove(Customer customer) {
        if (customer == null) {
            throw new IllegalArgumentException("Customer cannot be null");
        }

        this.em.remove(customer);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#findAll()
     */
    @Override
    public List<Customer> findAll() {

        TypedQuery<Customer> query = this.em.createQuery("FROM Customer", Customer.class);
        return query.getResultList();
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#findByLastName(java.lang.String)
     */
    @Override
    public List<Customer> findByLastName(String lastName) {

        if (lastName == null) {
            throw new IllegalArgumentException("lastName cannot be null");
        }

        TypedQuery<Customer> query = this.em.createQuery("SELECT c FROM Customer c WHERE c.lastName = :lastName",
                Customer.class).setParameter("lastName", lastName);
        return query.getResultList();
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#findByEmail(java.lang.String)
     */
    @Override
    public Customer findByEmail(String email) {

        if (email == null) {
            throw new IllegalArgumentException("email cannot be null");
        }

        TypedQuery<Customer> query = em.createQuery("SELECT c FROM Customer c WHERE c.email = :email",
                Customer.class).setMaxResults(1).setParameter("email", email);
        List<Customer> customers = query.getResultList();
        return customers.size() > 0 ? customers.get(0) : null;
    }

    /**
     * @see
     * cz.muni.fi.pa165.machineryrental.dao.CustomerDAO#findByCompanyNumber(java.lang.String)
     */
    @Override
    public Customer findByCompanyNumber(String companyNumber) {

        if (companyNumber == null) {
            throw new IllegalArgumentException("companyNumber cannot be null");
        }

        TypedQuery<Customer> query = this.em.createQuery("SELECT c FROM Customer c WHERE c.companyNumber = :companyNumber",
                Customer.class).setMaxResults(1).setParameter("companyNumber", companyNumber);
        List<Customer> result = query.getResultList();
        return result.size() > 0 ? result.get(0) : null;
    }
}
